import {ImDataBase} from './ImDataBaseH5' 
import { listMyChannelGroups } from '@/api/mdp/im/group/imGroup'
import { listImGroupMessage } from '@/api/mdp/im/group/imGroupMessage' 
import { listMyPrichatChannelGroups,listImPrichatMessage } from '@/api/mdp/im/prichat/imPrichatMessage'

export class ImClient {
  constructor(url, heartChecknterval,userid,clientType,branchId,categoryId) {
    this.url = url
    this.heartChecknterval = heartChecknterval
    this.imChannelId = '',
    this.userid=userid,
    this.sendTime=null,
    this.branchId=branchId,
    this.categoryId=categoryId
    this.clientType=clientType;//pc/andorid/wxa/ios/baidu/jrtt等
    this.imDataBase=new ImDataBase(userid);
    this.loadImDataFromServerWithConfig();
  }

  connect(callback) {
    var that=this;
    console.log(this);
    that.connectCallback = callback
    if (that.clientType=='uniapp'){
      that.conn = wx.connectSocket({
        url: that.url,
        header: {
          'content-type': 'application/json'
        },
        protocols: ['protocol1'],
        method: 'GET',
        success: function (res) {
          console.log('WebSocket连接创建', res);
          console.log(this); 
          //that.onOpen();
        },
        fail: function (err) { 
          console.log(err)
          that.connected = false
        },
      })
      console.log(this.conn);
      that.conn.onOpen( () => {
        that.connected = true
        that.onOpen()
      })

      that.conn.onClose( () => {
        that.connected = false
        that.onClose()
      })

      that.conn.onError( (event) => {
        that.onError(event)
      })

      that.conn.onMessage( (event) => {
        that.onMessage(event.data)
      })
    }else{
      this.conn = new WebSocket(this.url)
      console.log("IM连接地址：" + this.url);
      this.conn.onopen = () => {
        this.connected = true
        this.onOpen()
      }

      this.conn.onclose = () => {
        this.connected = false
        this.onClose()
      }

      this.conn.onerror = (event) => {
        this.onError(event)
      }

      this.conn.onmessage = (event) => {
        this.onMessage(event.data)
      }

    }
    
  }
  db(){
    return this.imDataBase.db;
  }
  heartCheckUtil = {
    start: () => {
      this.heartCheckObj = setTimeout(() => {
        //console.log("心跳里面的this");
        //console.log(this);
        if (this.conn && this.conn.readyState === 1) {
          if(this.clientType=='uniapp'){
            this.conn.send({data:''})
          }else{
            this.conn.send('')
          }
          
        }
      }, this.heartChecknterval)
    },

    reset: () => {
      clearTimeout(this.heartCheckObj)
      this.heartCheckUtil.start()
    },

    stop: () => {
      if (this.heartCheckObj) {
        clearTimeout(this.heartCheckObj)
      }
    }
  }

  reconnectUtil = {
    start: () => {
      this.reconnectObj = setTimeout(() => {
        // 已经关闭了与服务器的连接
        if (this.conn.readyState == 3) {
          console.log("与服务器的连接已关闭，现在开始重连")
          this.reconnectStarting = true
          this.connect(this.connectCallback)
        }
      }, 5000)
    },

    stop: () => {
      this.reconnectStarting = false
      if (this.reconnectObj) {
        clearTimeout(this.reconnectObj)
        this.reconnectObj = null
      }
    }
  }

  onOpen() {
	  console.log("websocket 已连接")
    if(this.connectCallback != null) {
      this.connectCallback(this)
      this.autoBindToChannelGroups();
    }
    const reconnectStarting = this.reconnectStarting
    this.reconnectUtil.stop()
    if (reconnectStarting && this.handleReconnectSuccessed) {
      this.handleReconnectSuccessed()
    }
    if(this.handleUserOnline) {
      this.handleUserOnline()
    }
    this.heartCheckUtil.start()
  }

  onClose() {
    console.log("与服务器的连接已被关闭");
    this.heartCheckUtil.stop()
    this.reconnectUtil.start()
    if(this.handleConnectionClosed) {
      this.handleConnectionClosed()
    }
    if(this.handleUserOffline) {
      this.handleUserOffline()
    }
  }

  onError(error) {
    console.error(error)
  }

  onMessage(message) {
    if (message !== '') {
    	console.log("收到服务器消息《《《《《《《《《《《");
      console.log(message)
      var message=JSON.parse(message);
      this.formatGroupName(message);
      this.formatSendContent(message);
      this.handleMessage(message)
    }
    this.heartCheckUtil.reset()
  }

  send(message) {
	  console.log("websocket 发送数据到服务器----------------"+this.connected) 
    if (this.connected) {
      if(message===''||message===null){
    	  return;
      }
      let msg=message;
      if(typeof(message)=='string'){
    	  msg=JSON.parse(message) 
      }
      msg.store='1'//是1就保存进mysql数据库

      if(this.branchId){
    	  msg.branchId=this.branchId
      }
      if(this.categoryId){
    	  msg.categoryId=this.categoryId
      }
      //如果是新消息，则将新消息存入客户端数据库，方便查询历史记录
      if(msg.action=='newMessage'){
        this.db().messages.put(msg);
      }
      //如果是消息状态报告，则把历史消息的状态改成新的状态
      if(msg.action=='messageStateReport'){
        this.db().messages.where("msgId").equals(msg.sourceMsgId).modify({msgState:msg.msgState});
      }
      
      let msgStr=JSON.stringify(msg); 
      console.log("websocket 发送的数据为：") 
       console.log(msgStr) 
       if(this.clientType=='uniapp'){
         this.conn.send({data:msgStr});
       }else{
         this.conn.send(msgStr)
       }
      
      this.heartCheckUtil.reset()
    }
  }

  handleMessage(message) {
    if(message.action!="messageRemoved" && message.action!="messageStateReport" ){
      this.db().messages.put(message);  
    }

    switch (message.action) {
      case "onlineStatusChanged":

        if (this.handleOnlineStatusChanged) {
          this.handleOnlineStatusChanged(message)
        }
        if(this.handleUserOnlineStatusChanged) {
          this.handleUserOnlineStatusChanged(message)
        }
        break
      case "nicknameChanged": 

        if (this.handleNicknameChanged) {
          this.handleNicknameChanged(message)
        }
        break
      case "avatarChanged": 

        if (this.handleAvatarChanged) {
          this.handleAvatarChanged(message)
        }
        break
      case "newMessage": 
        this.db().groupMessageState.where("groupId").equals(message.groupId).count(count=>{
          if(count>0){
            this.db().groupMessageState.where("groupId").equals(message.groupId).modify(groupMessageState=>{
              console.log("xxxxxxxxxxxxxxxxxxxgroupMessageState");
              console.log(groupMessageState); 
              if(!message.groupName){
                if(groupMessageState.groupName){
                  message.groupName=groupMessageState.groupName
                }
              }else{
                if(!groupMessageState.groupName){
                  groupMessageState.groupName=message.groupName
                }
              }
              groupMessageState.unreadMessagesCount=groupMessageState.unreadMessagesCount+1; 
            })
          }else if(count<=0){
            if(!message.groupName){
              if(message.sendUsername){
                message.groupName=message.sendUsername
              } 
            }
            this.db().groupMessageState.put(message);
          } 
          if (this.handleNewMessage) {
            this.handleNewMessage(message)
          } 
        }); 
        
        break
      case "hisMessage":
        if(this.handleHisMessage) {
          this.handleHisMessage(message)
        }
        break
      case "joinChannelGroup": 

        message.isPrichat="0"
        message.unreadMessagesCount=0;
        if(!message.categoryId){
          message.categoryId="common"
        }
        message.gstatus='1'
        message.guStatus='1'

        this.db().groupMessageState.bulkPut([message]);
        //this.bindToChannelGroups([message.groupId]);
        if(this.handleJoinChannelGroup) {
          this.handleJoinChannelGroup(message)
        }
        break 
      case "channelGroupCreate": 

        if(!message.gstatus){
          message.gstatus='1'
          message.guStatus='1'
          message.isPrichat='0'
        }
        message.unreadMessagesCount=0;
        
        this.db().groupMessageState.bulkPut([message])
        //this.bindToChannelGroups([message.groupId]);

        if(this.handleChannelGroupCreate) {
          this.handleChannelGroupCreate(message)
        }
        break
      case "messageRemoved":
        this.db().messages.delete( message.msgId )
        if(this.handleMessageRemove) {
          this.handleMessageRemove(message)
        }
        break
      case "channelGroupNameChanged": 

        this.db().groupMessageState.where({groupId:message.groupId}).modify({
          groupName:message.groupName
         })
        if(this.handleChannelGroupNameChanged) {
          this.handleChannelGroupNameChanged(message)
        }
        break
      case "membersCountChanged":
        if(this.handleMembersCountChanged) {
          this.handleMembersCountChanged(message)
        }
        break
      case "removeFromChannelGroup":
        
        var users=message.users;
        if(users && users.length>0){
          users.forEach(i=>{
            if(i.userid==this.userid){
              this.db().groupMessageState.where({groupId:message.groupId}).modify({guStatus:'4'}); 
            }
          })
        }
        if(this.handleRemoveFromChannelGroup) {
          this.handleRemoveFromChannelGroup(message)
        }
        break
      case "leaveChannelGroup":
         var users=message.users;
        if(users && users.length>0){
          users.forEach(i=>{
            if(i.userid==this.userid){
              this.db().groupMessageState.where({groupId:message.groupId}).modify({guStatus:'4'}); 
            }
          })
        }
        
        if(this.handleLeaveChannelGroup) {
          this.handleLeaveChannelGroup(message)
        }
        break
      case "channelGroupRemove":
 
        this.db().groupMessageState.where({groupId:message.groupId}).modify({gstatus:'2'}); 
        if(this.handleChannelGroupRemove) {
          this.handleChannelGroupRemove(message)
        }
        break
      case "messageStateReport":
        //如果是消息状态报告，则把历史消息的状态改成新的状态
        if(message.action=='messageStateReport'){
          this.db().messages.where("msgId").equals(message.sourceMsgId).modify({msgState:message.msgState,msgStateDesc:message.msgStateDesc});
        }
        if(this.handleMessageStateReport) {
          this.handleMessageStateReport(message)
        }

        break
    }
    if(message.action !='messageStateReport'){
      if(this.currentGroupId!=null && this.currentGroupId==message.groupId && this.handleCurrentGroupNewMessage){
          this.handleCurrentGroupNewMessage(message);
      } 
      if (this.handleUnreadMessage) {
        this.handleUnreadMessage(message)
      }
    }
  }

  bindOnlineStatusChanged(callback) {
    this.handleOnlineStatusChanged = callback
  }
  unbindOnlineStatusChanged() {
    this.handleOnlineStatusChanged = null
  }

  bindNicknameChanged(callback) {
    this.handleNicknameChanged = callback
  }
  unbindNicknameChanged() {
    this.handleNicknameChanged = null
  }

  bindAvatarChanged(callback) {
    this.handleAvatarChanged = callback
  }
  unbindAvatarChanged() {
    this.handleAvatarChanged = null
  }

  bindNewMessage(callback) {
    this.handleNewMessage = callback
  }
  unbindNewMesssage() {
    this.handleNewMessage = null
  }
  /**
   * @param {Object} callback
   * 监听当前组的消息
   */
  bindCurrentGroupNewMessage(groupId,callback) {
    this.currentGroupId=groupId;
    this.handleCurrentGroupNewMessage = callback
  }
    
  unbindCurrentGroupNewMessage() {
      this.currentGroupId=null;
      this.handleCurrentGroupNewMessage = null
  }
  bindHandleMessageStateReport(callback) {
    this.handleMessageStateReport = callback
  }
  unbindHandleMessageStateReport() {
    this.handleMessageStateReport = null
  }
  bindConnectionClosed(callback) {
    this.handleConnectionClosed = callback
  }
  unbindConnectionClosed() {
    this.handleConnectionClosed = null
  }

  bindReconnectSuccessed(callback) {
    this.handleReconnectSuccessed = callback
  }
  unbindReconnectSuccessed() {
    this.handleReconnectSuccessed = null
  }

  bindUnreadMessage(callback) {
    this.handleUnreadMessage = callback
  }
  unbindUnreadMessage() {
    this.handleUnreadMessage = null
  }

  bindHisMessage(callback) {
    this.handleHisMessage = callback
  }
  unbindHisMessage() {
    this.handleHisMessage = null
  }

  bindJoinChannelGroup(callback) {
    this.handleJoinChannelGroup = callback
  }
  unbindJoinChannelGroup() {
    this.handleJoinChannelGroup = null
  }

  bindUserOnlineStatusChanged(callback) {
    this.handleUserOnlineStatusChanged = callback
  }
  unbindUserOnlineStatusChanged() {
    this.handleUserOnlineStatusChanged = null
  }

  bindMessageRemove(callback) {
    this.handleMessageRemove = callback
  }
  unbindMessageRemove() {
    this.handleMessageRemove = null
  }

  bindChannelGroupNameChanged(callback) {
    this.handleChannelGroupNameChanged = callback
  }
  unbindChannelGroupNameChanged() {
    this.handleChannelGroupNameChanged = null
  }

  bindMembersCountChanged(callback) {
    this.handleMembersCountChanged = callback
  }
  unbindMembersCountChanged() {
    this.handleMembersCountChanged = null
  }

  bindRemoveFromChannelGroup(callback) {
    this.handleRemoveFromChannelGroup = callback
  }
  unbindRemoveFromChannelGroup() {
    this.handleRemoveFromChannelGroup = null
  }

  bindLeaveChannelGroup(callback) {
    this.handleLeaveChannelGroup = callback
  }
  unbindLeaveChannelGroup() {
    this.handleLeaveChannelGroup = null
  } 
  bindChannelGroupCreate(callback) {
    this.handleChannelGroupCreate = callback
  } 
  unbindChannelGroupCreate() {
    this.handleChannelGroupCreate = null
  }
  bindChannelGroupRemove(callback) {
    this.handleChannelGroupRemove = callback
  }
  unbindChannelGroupRemove() {
    this.handleChannelGroupRemove = null
  }

  bindUserOnline(callback) {
    this.handleUserOnline = callback
  }
  unbindUserOnline() {
    this.handleUserOnline = null
  }

  bindUserOffline(callback) {
    this.handleUserOffline = callback
  }
  unbindUserOffline() {
    this.handleUserOffline = null
  }
  loadImDataFromServerWithConfig(){
    var that=this;
      this.db().config.reverse().first(item=>{ 
        console.log("imDataBase.config.reverse()");
        console.log(item);
        if(item){
          that.loadImDataFromServer(item);
        }else{ 
          var timeConfig={groupMessageTime:null,prichatMessageTime:null,groupTime:null,prichatGroupTime:null};
          this.db().config.add(timeConfig).then(lastKey=>{
              timeConfig.id=lastKey
              that.loadImDataFromServer(timeConfig);
          }); 
          
        }
        

    }).catch(e=>{
      console.log("imDataBase.config.reverse()");
        console.log(e);
    });
  }
  loadImDataFromServer(timeConfig){
    /***/
    
    var that=this;
       console.log("添加群消息到本地数据库》");
      listImGroupMessage({userid:that.userid,pageSize:100,pageNum:1,lastLoadImDataTime:timeConfig.groupMessageTime}).then(res=>{
        var datas=res.data.data;

      if(datas!=null && datas.length>0){
        datas.forEach(i=>{
          that.formatGroupName(i);
          that.formatSendContent(i)
        })
        that.db().messages.bulkPut(datas).then(res2=>{
          this.dispatchLoadDataFromServerEvent('listImGroupMessage',datas); 
        }).catch(e=>{
          console.log("添加群消息到本地数据库出错-----------》");
          console.log(e);
        })
      }else{
        this.dispatchLoadDataFromServerEvent('listImGroupMessage'); 
      }
      var date=new Date();
      that.db().config.update(timeConfig.id,{groupMessageTime:date.getTime()});
      
    })
    
    console.log("添加私聊消息到本地数据库》"); 
    listImPrichatMessage({userid:that.userid,pageSize:100,pageNum:1,lastLoadImDataTime:timeConfig.prichatMessageTime}).then(res=>{
      var datas=res.data.data;

      if(datas!=null && datas.length>0){
        datas.forEach(i=>{
          that.formatGroupName(i);
          that.formatSendContent(i)
        })
        that.db().messages.bulkPut(datas).then(lastKey=>{
          this.dispatchLoadDataFromServerEvent('listImPrichatMessage',datas);
          var date=new Date();
          that.db().config.update(timeConfig.id,{prichatMessageTime:date.getTime()});
        }).catch(e=>{
          console.log("添加私聊消息到本地数据库出错-----------》");
          console.log(e);
        })
      }else{
        this.dispatchLoadDataFromServerEvent('listImPrichatMessage'); 
      }
    })
    let params={userid:that.userid,lastLoadImDataTime:timeConfig.groupTime}
    
    console.log("添加群聊组到本地数据库》"); 
    listMyChannelGroups(params).then(res => { 
      let channelGroups=res.data.data; 
      if(channelGroups.length<=0){
        this.dispatchLoadDataFromServerEvent('listMyChannelGroups'); 
        return;
      }
      
      channelGroups.forEach(i=>{
        that.formatGroupName(i);
        //that.formatSendContent(i)
      })
      that.db().groupMessageState.bulkPut(channelGroups).then(lastKey=>{
          this.dispatchLoadDataFromServerEvent('listMyChannelGroups',channelGroups);
            var date=new Date();
            that.db().config.update(timeConfig.id,{groupTime:date.getTime()}); 
        }).catch(code,e=>{ 
          console.log("添加群聊组到本地数据库出错-----------》");
          console.log(e);
        });   
    }).catch(error => {
      ////outputError(this, error)
    })
     console.log("添加私聊组到本地数据库》"); 
     params={userid:that.userid,lastLoadImDataTime:timeConfig.prichatGroupTime}
    listMyPrichatChannelGroups(params).then(res => {
      var groups=res.data.data 
      if(!groups || groups.length==0){
        this.dispatchLoadDataFromServerEvent('listMyPrichatChannelGroups');
        return;
      }
      groups.forEach(i=>{
        that.formatGroupName(i);
        //that.formatSendContent(i)
      })
      that.db().groupMessageState.bulkPut(groups).then(lastKey=>{
           var date=new Date();
           this.dispatchLoadDataFromServerEvent('listMyPrichatChannelGroups',groups);
           that.db().config.update(timeConfig.id,{prichatGroupTime:date.getTime()});
         }).catch(e=>{
          console.log("添加私聊组到本地数据库出错-----------》");
          console.log(e);
        });    
    }).catch(error => {
      ////outputError(this, error)
    })
     
  }
  
  bindToChannelGroups(groupIds) {
    var that =this; 
      let message = {
        action: 'bindChannelToGroups',
        groupIds: groupIds,
        msgType:'group'
      }
      that.send(message)   
  }
  autoBindToChannelGroups() {
    var that =this;
    that.db().groupMessageState.where({isPrichat:'0',guStatus:'1',gstatus:'1'}).reverse().sortBy('sendTime',items=>{
       that.bindToChannelGroups(items.map(i=>i.groupId));
    }).catch(e=>{
      console.log(e);
    });
      
  }
  /**
   * 从服务器从新加载数据事件
   * listMyChannelGroups / listImGroupMessage / listImPrichatMessage/ listMyPrichatChannelGroups
   */
  dispatchLoadDataFromServerEvent(event,data){
    if(this.onLoadDataFromServer){
      this.onLoadDataFromServer(event,data);
    }
  }
  bindOnloadDataFromServer(callback){
    this.onLoadDataFromServer=callback
  } 
  formatGroupName(group){
    if(group.groupName){
      return 
    }
    if(group.msgType=="prichat" || group.isPrichat=='0'){
      if(this.userid==group.sendUserid){
        if(group.toUsername){
          group.groupName=group.toUsername
        }
      }else if(this.userid==group.toUserid){
        if(group.sendUsername){
          group.groupName= group.sendUsername;
        } 
      }
    }else if(group.msgType=="group" ||  group.isPrichat=='1'){
      if(group.action=="joinChannelGroup"){
       this.db().groupMessageState.where({groupId:group.groupId}).first(i=>{
          if(i.groupName){
            group.groupName=i.groupName
          }else{
            group.groupName=group.groupId
          }
        })
      }else{
        if(!group.groupName){
          if(this.userid==group.sendUserid){
            if(group.toUsername){
              group.groupName=group.toUsername
            }
          }else if(this.userid==group.toUserid){
            if(group.sendUsername){
              group.groupName= group.sendUsername;
            }
          } 
        }
      }
      
    }
     
  }
  formatSendContent(message){
    
    if(!message.sendContent){
      if(message.action=="leaveChannelGroup"){ 
          var users=message.users;
          if(users && users.length>0){
            message.sendContent=users.map(i=>i.username).join(",")+"已经离开群聊"
          } 
      }else if(message.action=="removeFromChannelGroup"){
        var users=message.users;
          if(users && users.length>0){
            message.sendContent=users.map(i=>i.username).join(",")+"已被移出群聊"
          } 
      }else if(message.action=="channelGroupCreate"){
          var users=message.users;
          if(users && users.length>0){
            if(message.cusername){
              message.sendContent=users.map(i=>i.username).join(",")+"加入"+message.cusername+"创建的群聊" 
            }else{
              message.sendContent=users.map(i=>i.username).join(",")+"加入群聊"  
            }
          }else{
            if(message.cusername){
              message.sendContent= message.cusername+"创建群聊" 
            }else{
              message.sendContent="新建群聊"
            }
          }
      }else if(message.action=="joinChannelGroup"){
        var users=message.users;
        if(users && users.length>0){ 
            message.sendContent=users.map(i=>i.username).join(",")+"加入群聊"  
            if(!message.groupName){
              message.groupName=users.map(i=>i.username).join(",")+"加入群聊"  
            }
        } 
      }
    }
  }
}